/*
Automatic clinic tests using a robot arm.
Copyright (C) 2010  CIC-CPC, CHU Gabriel Montpied
All other trademarks, logos and copyrights are the property
of their respective owners.

This file is part of cpc-painbot.

cpc-painbot is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpc-painbot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with cpc-painbot.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "asservissement/asservissement.h"

#include <QSignalMapper>
#include <QDebug>

#include "asservissement/regulateur.h"
#include "capteur.h"
#include "Pilotable.h"

Asservissement::Asservissement(QObject *parent) :
    QObject(parent),
    map_capteurs_(new QSignalMapper(this)),
    map_asservis_(new QSignalMapper(this))
{
    connect(map_capteurs_, SIGNAL(mapped(QString)), this, SLOT(capteurPret(QString)));
    connect(map_asservis_, SIGNAL(mapped(QString)), this, SLOT(asserviPret(QString)));
}

void Asservissement::setCapteur(const QString &nom, Capteur *capteur)
{
    Q_ASSERT_X(capteur != 0, "Asservissement::setCapteur", "Capteur nul");

    if ( capteurs_.contains(nom) ) {
        // Un capteur de ce nom existe
        // On le déconnecte
        mapCapteurs()->removeMappings(capteurs_[nom]);
    }

    // ajouter le capteur.
    capteurs_.insert(nom, capteur);

    // Le connecter.
    connect(capteur, SIGNAL(mesure(QVariant)), mapCapteurs(), SLOT(map()));
    mapCapteurs()->setMapping(capteur, nom);
}

void Asservissement::setAsservi(const QString &nom, Pilotable *asservi, const char *signal)
{
    Q_ASSERT_X(asservi != 0, "Asservissement::setAsservi", "Asservi nul");
    Q_ASSERT_X(signal != 0, "Asservissement::setAsservi", "Pas de signal fourni");

    if ( asservis_.contains(nom) )
        mapAsservis()->removeMappings(asservis_[nom]);

    asservis_.insert(nom, asservi);

    connect(asservi, signal, mapAsservis(), SLOT(map()));
    mapAsservis()->setMapping(asservi, nom);
}

void Asservissement::capteurPret(const QString &capteur)
{
    capteurs_prets_.insert(capteur);

    if ( capteursPrets() ) {
        qDebug() << "Les capteurs sont prêts.";
        capteurs_prets_.clear();
        asservis_prets_.clear();
        reguler();
    }
}

void Asservissement::asserviPret(const QString &asservi)
{
/*
    asservis_prets_.insert(asservi);

    if ( systemePret() ) {
        qDebug() << "Les asservis sont prets";
        capteurs_prets_.clear();
        asservis_prets_.clear();
        reguler();
    }
*/
}


void Asservissement::reguler() const
{
    Q_ASSERT_X(regulateur_ != 0, "Asservissement::reguler", "Aucun régulateur défini");
    qDebug() << "Asservissement::reguler, régulation";
    regulateur_->reguler(this);
}
